// Copyright (C) 1953-2022 NUDT
// Verilog module name - time_slot_calculation 
// Version: V4.0.20220526
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         calculation of time slot 
//             - calculate time slot according to syned global time and time slot length.
///////////////////////////////////////////////////////////////////////////
`timescale 1ns/100ps

module time_slot_calculation
#(
parameter clk_period = 24'h080000//8ns
)
(
       i_clk,
       i_rst_n,
       
       i_cycle_start,
       
       iv_time_slot_length,
       iv_slot_period,
       
       ov_time_slot,
       o_time_slot_switch       
);

// I/O
// clk & rst
input                  i_clk;
input                  i_rst_n;
// calculation of time slot
input                  i_cycle_start;         
input      [10:0]      iv_time_slot_length;    // measure:us; 10 means time slot length is 10us.
// period of injection slot table
input      [10:0]      iv_slot_period;//measure:time slot period. 
// time slot
output reg [9:0]       ov_time_slot;//current time slot 
output reg             o_time_slot_switch;       
//*******************cycle cnt**********************
reg   [6:0]            rv_cycle_cnt;
reg   [1:0]            rv_cycle_cnt_state;
localparam             IDLE_S                   = 2'd0,
                       COUNT_CYCLE_S            = 2'd1;
always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n)begin
        rv_cycle_cnt       <= 7'd0;
        rv_cycle_cnt_state <= IDLE_S;
    end
    else begin
        case(rv_cycle_cnt_state)
            IDLE_S:begin
                if(i_cycle_start)begin
                    rv_cycle_cnt       <= 7'd1;
                    rv_cycle_cnt_state <= COUNT_CYCLE_S;
                end
                else begin
                    rv_cycle_cnt       <= 7'd0;
                    rv_cycle_cnt_state <= IDLE_S;
                end
            end
            COUNT_CYCLE_S:begin
                if(i_cycle_start)begin
                    rv_cycle_cnt       <= 7'd0;
                end
                else begin
                    if(rv_cycle_cnt == 7'd124)begin
                        rv_cycle_cnt       <= 7'd0;
                    end
                    else begin
                        rv_cycle_cnt       <=  rv_cycle_cnt + 1'b1;
                    end
                end
            end
            default:begin
                rv_cycle_cnt       <= 7'd0;
                rv_cycle_cnt_state <= IDLE_S;            
            end
        endcase            
    end
end 
//*******************us cnt**********************
reg   [10:0]    rv_us_cnt;
always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n)begin
        rv_us_cnt          <= 11'd0;      
    end
    else begin
        if(i_cycle_start)begin
            rv_us_cnt      <= 11'd0;           
        end
        else begin
            if(rv_cycle_cnt == 7'd124)begin
                if(rv_us_cnt == (iv_time_slot_length - 1'b1))begin
                    rv_us_cnt       <= 11'd0; 
                end
                else begin
                    rv_us_cnt       <= rv_us_cnt + 1'b1; 
                end
            end
            else begin
                rv_us_cnt           <= rv_us_cnt;
            end            
        end        
    end
end 
//***************************************************
//                time slot count
//***************************************************  
always @(posedge i_clk or negedge i_rst_n) begin
    if(!i_rst_n)begin
        ov_time_slot       <= 10'd0;
        o_time_slot_switch <= 1'b0 ;
    end
    else begin
        if(i_cycle_start)begin
            ov_time_slot       <=  10'd0;
            o_time_slot_switch <=  1'b1 ;
        end
        else begin
            if(ov_time_slot == (iv_slot_period - 1'b1))begin
                ov_time_slot       <=  ov_time_slot;
                o_time_slot_switch <=  1'b0 ;            
            end
            else begin
                if((rv_cycle_cnt == 7'd124)&&(rv_us_cnt == (iv_time_slot_length - 1'b1)))begin
                    ov_time_slot       <=  ov_time_slot + 1'b1;
                    o_time_slot_switch <=  1'b1 ;
                end
                else begin
                    o_time_slot_switch <=  1'b0 ; 
                end
            end
        end            
    end
end

endmodule

